package com.score;

import android.content.Context;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;

/**
 * Created by Roger on 2018/4/2.
 */

public class Decoder {

    private boolean mIsStop;
    private Context mContext;
    private DataBuffer mDataBuffer;
    private String mBanzouFilePath;

    public Decoder(Context context, DataBuffer buff, String banzouFilePath) {
        mContext = context;
        mDataBuffer = buff;
        mBanzouFilePath=banzouFilePath;
    }

    public void startPlay() {
        mIsStop = false;
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    MediaExtractor mediaExtractor = new MediaExtractor();
                    MediaCodec codec = null;
                    try {
                        mediaExtractor.setDataSource(mBanzouFilePath);
                        for (int i = 0; i < mediaExtractor.getTrackCount(); i++) {
                            MediaFormat format = mediaExtractor.getTrackFormat(i);
                            String mime = format.getString(MediaFormat.KEY_MIME);
                            if (mime.startsWith("audio")) {
                                mediaExtractor.selectTrack(i);
                                Log.w("debugg", mediaExtractor.getTrackFormat(i).toString());
                                float sec = 1f * mediaExtractor.getTrackFormat(i).getLong(MediaFormat.KEY_DURATION) / 1000 / 1000;
                                codec = MediaCodec.createDecoderByType(mime);
                                codec.configure(format, null, null, 0);
                                break;
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        return;
                    }
                    codec.start();

                    while (!mIsStop) {
                        ByteBuffer[] inputBuffers = codec.getInputBuffers();
                        ByteBuffer[] outputBuffers = codec.getOutputBuffers();
                        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
                        int inputIndex = codec.dequeueInputBuffer(10000);
                        if (inputIndex < 0) {
                            break;
                        }
                        ByteBuffer inputBuffer = inputBuffers[inputIndex];
                        inputBuffer.clear();
                        int sampleSize = mediaExtractor.readSampleData(inputBuffer, 0);
                        if (sampleSize < 0) {
                            codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                            mediaExtractor.advance();
                        } else {
                            codec.queueInputBuffer(inputIndex, 0, sampleSize, 0, 0);
                            mediaExtractor.advance();
                        }

                        int outputIndex = codec.dequeueOutputBuffer(bufferInfo, 10000);

                        ByteBuffer outputBuffer;
                        byte[] chunkPCM;
                        while (outputIndex >= 0) {//每次解码完成的数据不一定能一次吐出 所以用while循环，保证解码器吐出所有数据
                            outputBuffer = outputBuffers[outputIndex];//拿到用于存放PCM数据的Buffer
                            int size = bufferInfo.size;
                            if (size > 0) {
                                chunkPCM = new byte[size];//BufferInfo内定义了此数据块的大小
                                outputBuffer.get(chunkPCM);//将Buffer内的数据取出到字节数组中
                                outputBuffer.clear();//数据取出后一定记得清空此Buffer MediaCodec是循环使用这些Buffer的，不清空下次会得到同样的数据

                                while (mDataBuffer.getLeft() <= size) {
                                    try {
                                        Thread.sleep(10);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                                mDataBuffer.pushData(chunkPCM);
                            }
                            codec.releaseOutputBuffer(outputIndex, false);//此操作一定要做，不然MediaCodec用完所有的Buffer后 将不能向外输出数据
                            outputIndex = codec.dequeueOutputBuffer(bufferInfo, 10000);//再次获取数据，如果没有数据输出则outputIndex=-1 循环结束
                        }
                    }
                    codec.flush();
                    codec.release();
                    mediaExtractor.release();
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        }.start();
    }

    public void stopPlay() {
        mIsStop = true;
    }


}
